﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Media.Imaging;
using System.Windows.Media;

namespace ImageProcessing
{

    public static class ALOperations
    {
        #region Arithmetical

        public static void AddConstant(WriteableBitmap image, byte constant)
        { GlobalOperations.ImageAndConstantOperation(image, new ByteConstOperation((pixel_byte, cons) => { return (byte)Math.Min(255, pixel_byte + cons[0]); }), constant); }

        public static void SubtractConstant(WriteableBitmap image, byte constant)
        { GlobalOperations.ImageAndConstantOperation(image, new ByteConstOperation((pixel_byte, cons) => { return (byte)Math.Max(0, pixel_byte - cons[0]); }), constant); }

        public static void MultipleOnConstant(WriteableBitmap image, double constant)
        { GlobalOperations.ImageAndConstantOperation(image, new ByteConstOperation((pixel_byte, cons) => { return (byte)Math.Min(255, pixel_byte * cons[0]); }), constant); }

        public static void DivideOnConstant(WriteableBitmap image, double constant)
        { GlobalOperations.ImageAndConstantOperation(image, new ByteConstOperation((pixel_byte, cons) => { return (byte)(pixel_byte / cons[0]); }), constant); }

        public static WriteableBitmap SumAandB(WriteableBitmap a_image, WriteableBitmap b_image)
        { return GlobalOperations.ImageAndImageOperation(a_image, b_image, new BytesOperation((a_pixel, b_pixel) => { return (byte)Math.Min(255, a_pixel + b_pixel); })); }

        public static WriteableBitmap SubtractBfromA(WriteableBitmap a_image, WriteableBitmap b_image)
        { return GlobalOperations.ImageAndImageOperation(a_image, b_image, new BytesOperation((a_pixel, b_pixel) => { return (byte)Math.Max(0, a_pixel - b_pixel); })); }

        #endregion

        #region Logical

        public static void LogicalAndConstant(WriteableBitmap image, ushort constant)
        { GlobalOperations.ImageAndConstantOperation(image, new ByteConstOperation((pixel_byte, cons) => { return (byte)(pixel_byte & (byte)cons[0]); }), constant); }

        public static void LogicalOrConstant(WriteableBitmap image, ushort constant)
        { GlobalOperations.ImageAndConstantOperation(image, new ByteConstOperation((pixel_byte, cons) => { return (byte)(pixel_byte | (byte)cons[0]); }), constant); }

        public static void LogicalXorConstant(WriteableBitmap image, ushort constant)
        { GlobalOperations.ImageAndConstantOperation(image, new ByteConstOperation((pixel_byte, cons) => { return (byte)(pixel_byte ^ (byte)cons[0]); }), constant); }

        public static WriteableBitmap LogicalAandB(WriteableBitmap a_image, WriteableBitmap b_image)
        { return GlobalOperations.ImageAndImageOperation(a_image, b_image, new BytesOperation((a_pixel, b_pixel) => { return (byte)(a_pixel & b_pixel); })); }

        public static WriteableBitmap LogicalAorB(WriteableBitmap a_image, WriteableBitmap b_image)
        { return GlobalOperations.ImageAndImageOperation(a_image, b_image, new BytesOperation((a_pixel, b_pixel) => { return (byte)(a_pixel | b_pixel); })); }

        public static WriteableBitmap LogicalAxorB(WriteableBitmap a_image, WriteableBitmap b_image)
        { return GlobalOperations.ImageAndImageOperation(a_image, b_image, new BytesOperation((a_pixel, b_pixel) => { return (byte)(a_pixel ^ b_pixel); })); }

        #endregion
    }
}
